package littlecyberwar.tool;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.util.*;

import littlecyberwar.ui.*;


// a common superclass for different kind of mouse action to game command
// i.e. move straight ahead
// rotate
// side step, etc.
public class MouseRotateRightHandler extends MouseRotateHandler {

  // double startDragX, startDragY;
//  Point2D pivotP;
//  double width;
//  double startDragX, startDragY, pivotX, pivotY;
//  double startAngle;

  public MouseRotateRightHandler() {
    super();
    // startDragX = -1;
    // startDragY = -1;
    id = H_ROTATERIGHT;
	unitSelectedText = "Drag mouse around the unit right-front corner and release button to rotate unit.";
	noUnitSelectedText = "Click on unit to select for right rotation.";

  }

  public void startAction( MouseEvent e ) {
    super.startAction(e);
  }

  double getCurrentDiameter(boolean isCombinedShape){
	  double largestWidth= 0;
	  if ( isCombinedShape == false ){
		  // need to find the largest element
		  for ( int i=0; i < selectedElements.size(); i++ ) {
			  Element el = ((SelectedElementContainer)selectedElements.get(i)).element;
			  double currWidth =el.getWidth(); 
			  if ( currWidth > largestWidth ){
				  largestWidth = currWidth;
			  }
		  }
			
	  }else{
		  /**			  
		   *if combined shape, then need to figure out the combined shape
		   * then take the distance from the center of the combined shape,
		   * the largestWidth is then the distance from the right front corner 
		   * of the rightmost unit, all the way to the pivot point
		   * 
		   * 1. transform all elements into the origin according to the selected element 
		   * 2. sort all the selected elements from left to right
		   * 3. take the left most unit and put into "possible" pile
		   * 4. any elements within 1/2 base width of another tile in the "possible" pile also joins the possible pile
		   * 5. Take the "front" most unit from the possible pile.
		   * 6. its right front is the pivot point 
		   */
		  Element refEl = ((SelectedElementContainer)selectedElements.get(0)).element;
		  AffineTransform refTrans = refEl.getTransform();			
		  ArrayList sortList = new ArrayList();
					
		  /**
		   * Now loop through all the selected elements, and then inverse
		   * transform their left front point onto the reference coordinate
		   */
		  for ( int i=0; i < selectedElements.size(); i++ ) {
			  SelectedElementContainer cont = ((SelectedElementContainer)selectedElements.get(i));
			  Element el = cont.element;			  	
			  Point2D rightFrontP = el.getFinalRightFrontPoint();
			  Point2D rfpRefCoordinate = null;
			  try {
				rfpRefCoordinate = refTrans.inverseTransform(rightFrontP, rfpRefCoordinate);
			  } catch ( Exception ex ){
				  ex.printStackTrace();
			  }
			  GroupSortElementHolder holder = new GroupSortElementHolder();
			  holder.cont = cont;
			  holder.refPointX = rfpRefCoordinate.getX();
			  holder.refPointY = rfpRefCoordinate.getY();
				
			  sortList.add(holder);
		  }
	
		  // now sort the containers. At the end the last element in the array
		  // would be the right most
		  Collections.sort(sortList);
			
		  // now move anyone within 1/2 base width of the possible pile into the possible pile
		  ArrayList possiblePile = new ArrayList(selectedElements.size());
						
		  SecondaryGroupSortElementHolder poss = getSecondaryGroupSortElementHolder((GroupSortElementHolder)sortList.get(sortList.size()-1));			
		  possiblePile.add(poss);
			
		  for ( int i=1; i < sortList.size(); i++ ) {
			  GroupSortElementHolder currHolder = (GroupSortElementHolder)sortList.get(i);
			  boolean isPossible = compareCloseElementsInGroupAlignment(currHolder, possiblePile);
			  if ( isPossible ){
				  poss = getSecondaryGroupSortElementHolder(currHolder);
				  possiblePile.add(poss);	
			  }
		  }
			
		  // now the possible pile will have to sorted by the along the Y axis
		  // the smallest Y value will become the pivot element
		  //
		  Collections.sort(possiblePile);

		  // setup the pivot point here
		  poss = (SecondaryGroupSortElementHolder)possiblePile.get(0);	
		  Element pivotEl = poss.cont.element;		
		  pivotP = pivotEl.getFinalRightFrontPoint();
		  pivotX = pivotP.getX();
		  pivotY = pivotP.getY();
			
		  // calculate dist from left front to right front of rightmost element
		  GroupSortElementHolder leftMostHolder = (GroupSortElementHolder)(sortList.get(0));
		  Point2D leftMostPoint = leftMostHolder.cont.element.getFinalLeftFrontPoint();
						
		  largestWidth=leftMostPoint.distance(pivotP);
	  }
	  return(largestWidth);
  }
 
  SecondaryGroupSortElementHolder getSecondaryGroupSortElementHolder(GroupSortElementHolder gh ){
	  SecondaryGroupSortElementHolder poss = new SecondaryGroupSortElementHolder();
	  poss.cont = gh.cont;
	  poss.refPointX = gh.refPointX;
	  poss.refPointY = gh.refPointY; 
	  return ( poss );		
  }
  /**
   * If the currHolder refPointX coordinate is < 1/2 of the width of any other
   * @param currHolder
   * @param possiblePile
   * @return true if this is also a possible pile
   */ 
  boolean compareCloseElementsInGroupAlignment(
	  GroupSortElementHolder currHolder, 
	  ArrayList possiblePile) {
		
	  boolean val = false;
		
	  for ( int i=0; i < possiblePile.size(); i++ ){
		  SecondaryGroupSortElementHolder h = (SecondaryGroupSortElementHolder)possiblePile.get(i);
		  double x = h.refPointX;
		  double halfwidth = h.cont.element.getWidth() /2;
		  if ( currHolder.refPointX > (x-halfwidth)) {
			  val = true;
			  break;
		  }
	  }
	  return ( val );
  }

  // must be called after getCurrentDiameter()
void setGroupPivotParam() {	
  for ( int i=0; i < selectedElements.size(); i++ ){
	  SelectedElementContainer cont = ((SelectedElementContainer)selectedElements.get(i));
		
	  /**
	   * For the halfHeight and halfWidth, we have to take the pivotX,
	   * inverse transform it back to the coordinate of the shape 
	   */
	  Element el = cont.element;
	  AffineTransform elTrans = el.getTransform();
	  Point2D invTransedPivotP = null;
		
	  try {
		  invTransedPivotP = elTrans.inverseTransform(pivotP, invTransedPivotP );
						
	  } catch ( Exception ex ) {
		  ex.printStackTrace();
	  }

	  cont.halfWidth = invTransedPivotP.getX();
	  cont.halfHeight = invTransedPivotP.getY();
  }
  // in case of group select, the pivotX, pivotY, and pivotP are all set
  return;
}

  void setPivotParam() {
	clockwise = true; // set this to default
	for ( int i=0; i < selectedElements.size(); i++ ){
		SelectedElementContainer cont = ((SelectedElementContainer)selectedElements.get(i));
		currEl = cont.element;
		cont.halfWidth = currEl.getWidth();
		cont.halfHeight = 0;
	}
	currEl = ((SelectedElementContainer)selectedElements.get(0)).element;
	Shape selRec = currEl.getFinalShape();
	
	pivotP = currEl.getFinalRightFrontPoint();
	pivotX = pivotP.getX();
	pivotY = pivotP.getY();
	
	fullWidth *= 2;
	//	startAngle = Math.atan2((startDragY-pivotY),(startDragX-pivotX));
	//	origStartAngle = startAngle;	
  }
}